package Netty_impro;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.ByteProcessor;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;

public class client {
    public static void main(String[] args) throws InterruptedException {
        //start();

        //通过短链接解决黏包  但效率太低了
        /*for (int i=0;i<10;i++){
            start2();
        }*/


        /*
         还可以让服务端加入这行代码，接收固定长度（8字节）的信息
        ch.pipeline().addLast(new FixedLengthFrameDecoder(8));
         */

        /*客户端还可以通过在每条消息后面加入\n解决*/

        //通过预设定的长度解决
        start3();
    }

    public static void start() throws InterruptedException {
        NioEventLoopGroup worker=new NioEventLoopGroup();
        ChannelFuture cf= new Bootstrap()
                .group(worker)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){
                            @Override
                            public void channelActive(ChannelHandlerContext ctx) throws Exception {
                                /*
                                服务端出现黏包
                                System.out.println("sending the message!");
                                for (int i=0;i<10;i++){
                                    ByteBuf buffer = ctx.alloc().buffer(16);
                                    buffer.writeBytes(new byte[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16});
                                    ctx.writeAndFlush(buffer);
                                }*/
                                ByteBuf byteBuf=ctx.alloc().buffer();
                                for (int i=0;i<100;i++){
                                    byteBuf.writeBytes(new byte[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16});
                                }
                                ctx.writeAndFlush(byteBuf);
                            }
                        });
                    }
                }).connect("localhost", 8080);

        cf.sync();
        cf.channel().closeFuture().sync();
        worker.shutdownGracefully();
    }

    public static void start2() throws InterruptedException {
        NioEventLoopGroup worker=new NioEventLoopGroup();
        ChannelFuture cf= new Bootstrap()
                .group(worker)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){
                            @Override
                            public void channelActive(ChannelHandlerContext ctx) throws Exception {
                                /*
                                服务端出现黏包
                                System.out.println("sending the message!");
                                for (int i=0;i<10;i++){
                                    ByteBuf buffer = ctx.alloc().buffer(16);
                                    buffer.writeBytes(new byte[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16});
                                    ctx.writeAndFlush(buffer);
                                }*/
                                ByteBuf byteBuf=ctx.alloc().buffer();
                                byteBuf.writeBytes(new byte[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16});

                                ctx.writeAndFlush(byteBuf);
                                ctx.close();
                            }
                        });
                    }
                }).connect("localhost", 8080);

        cf.sync();
        cf.channel().closeFuture().sync();
        worker.shutdownGracefully();
    }

    public static void start3() throws InterruptedException {
        NioEventLoopGroup worker=new NioEventLoopGroup();
        ChannelFuture cf= new Bootstrap()
                .group(worker)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){
                            @Override
                            public void channelActive(ChannelHandlerContext ctx) throws Exception {
                                /*
                                服务端出现黏包
                                System.out.println("sending the message!");
                                for (int i=0;i<10;i++){
                                    ByteBuf buffer = ctx.alloc().buffer(16);
                                    buffer.writeBytes(new byte[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16});
                                    ctx.writeAndFlush(buffer);
                                }*/
                                ByteBuf byteBuf= ctx.alloc().buffer();
                                for (int i=0;i<10;i++){
                                    int random=(int)(Math.random()*10+5);
                                    byteBuf.writeInt(random);
                                    for (int j=0;j<random;j++){
                                        byteBuf.writeByte(j);
                                    }
                                }
                                ctx.writeAndFlush(byteBuf);
                            }
                        });
                    }
                }).connect("localhost", 8080);

        cf.sync();
        cf.channel().closeFuture().sync();
        worker.shutdownGracefully();
    }

}
